# LeetCode 16、最接近三数之和
# 一、题目描述
给你一个长度为 n
的整数数组 nums
和 一个目标值 target
。请你从 nums
中选出三个整数,使它们的和与 target
最接近。
返回这三个数的和。
假定每组输入只存在恰好一个解。
# 二、题目解析
# 三、参考代码
# 1、Java 代码
// 登录 AlgoMooc 官网获取更多算法图解
// https://www.algomooc.com
// 作者:程序员吴师兄
// 代码有看不懂的地方一定要私聊咨询吴师兄呀
// 最接近的三数之和(16):https://leetcode-cn.com/problems/3sum-closest/submissions/
class Solution {
public int threeSumClosest(int[] nums, int target) {
// 题目假定每组输入只存在恰好一个解,所以不需要处理边界情况
int ans = nums[0] + nums[1] + nums[2];
// 先将数组进行排序操作,从小到大
Arrays.sort(nums);
// 开始遍历整个数组
// 在遍历的过程中,观察设置的三个位置的元素之后的大小
// num[i] 为从左到右观察过去的元素
// left 为从 i 到 len - 1 的元素
// right 为从 len - 1 向左移动到 i 的元素
for (int i = 0; i < nums.length ; i++) {
// left 为从 i 到 len - 1 的元素,向右移动
int left = i + 1;
// right 为从 len - 1 向左移动到 i 的元素,向左移动
int right = nums.length - 1;
// left 和 right 不断的向内移动
while(left < right){
// 计算这三者之和
int sum = nums[i] + nums[left] + nums[right];
// 寻找出更接近于 target 的那个和
if(Math.abs(target - sum) < Math.abs(target - ans)){
ans = sum;
}
// 如果三者之和小于 target ,那么说明需要找更大的数
if (sum < target){
// left 向右移动
left++;
// 如果三者之和大于 target ,那么说明需要找更小的数
}else if (sum > target) {
// right 向左移动
right--;
}else{
return ans;
}
}
}
// 返回结果
return ans;
}
}
# **2、**C++ 代码
// 登录 AlgoMooc 官网获取更多算法图解
// https://www.algomooc.com
// 作者:程序员吴师兄
// 代码有看不懂的地方一定要私聊咨询吴师兄呀
// 最接近的三数之和(16):https://leetcode-cn.com/problems/3sum-closest/submissions/
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
// 题目假定每组输入只存在恰好一个解,所以不需要处理边界情况
int ans = nums[0] + nums[1] + nums[2];
// 先将数组进行排序操作,从小到大
sort(nums.begin(), nums.end());
// 开始遍历整个数组
// 在遍历的过程中,观察设置的三个位置的元素之后的大小
// num[i] 为从左到右观察过去的元素
// left 为从 i 到 len - 1 的元素
// right 为从 len - 1 向左移动到 i 的元素
for (int i = 0; i < nums.size() ; i++) {
// left 为从 i 到 len - 1 的元素,向右移动
int left = i + 1;
// right 为从 len - 1 向左移动到 i 的元素,向左移动
int right = nums.size() - 1;
// left 和 right 不断的向内移动
while(left < right){
// 计算这三者之和
int sum = nums[i] + nums[left] + nums[right];
// 寻找出更接近于 target 的那个和
if(abs(target - sum) < abs(target - ans)){
ans = sum;
}
// 如果三者之和小于 target ,那么说明需要找更大的数
if (sum < target){
// left 向右移动
left++;
// 如果三者之和大于 target ,那么说明需要找更小的数
}else if (sum > target) {
// right 向左移动
right--;
}else{
return ans;
}
}
}
// 返回结果
return ans;
}
};
# 3、Python 代码
# 登录 AlgoMooc 官网获取更多算法图解
# https://www.algomooc.com
# 作者:程序员吴师兄
# 代码有看不懂的地方一定要私聊咨询吴师兄呀
# 最接近的三数之和(16):https://leetcode-cn.com/problems/3sum-closest/submissions/
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
# 题目假定每组输入只存在恰好一个解,所以不需要处理边界情况
ans = nums[0] + nums[1] + nums[2]
# 先将数组进行排序操作,从小到大
nums.sort()
# 开始遍历整个数组
# 在遍历的过程中,观察设置的三个位置的元素之后的大小
# num[i] 为从左到右观察过去的元素
# left 为从 i 到 len - 1 的元素
# right 为从 len - 1 向左移动到 i 的元素
for i in range(len(nums)) :
# left 为从 i 到 len - 1 的元素,向右移动
left = i + 1
# right 为从 len - 1 向左移动到 i 的元素,向左移动
right = len(nums) - 1
# left 和 right 不断的向内移动
while left < right :
# 计算这三者之和
sum = nums[i] + nums[left] + nums[right]
# 寻找出更接近于 target 的那个和
if abs(target - sum) < abs(target - ans) :
ans = sum
# 如果三者之和小于 target ,那么说明需要找更大的数
if sum < target :
# left 向右移动
left += 1
# 如果三者之和大于 target ,那么说明需要找更小的数
elif sum > target :
# right 向左移动
right -= 1
else :
return ans
# 返回结果
return ans
# 四、复杂度分析
时间复杂度:O(N^2),其中 N 是数组 nums 的长度。
空间复杂度:O(logN)。